home *** CD-ROM | disk | FTP | other *** search
- /*
- * IGMP/ICMP/IPIP/IDP/RSVP/IPIP/IPPROTO_RAW KERNEL CHECKER
- *
- * These protocols have the same pr_usrreqs... This is a kld to monitor
- * their packets via FreeBSD kernel.
- *
- * idea & code by pIGpEN [pigpen@s0ftpj.org, deadhead@sikurezza.org ]
- *
- * Tested on FreeBSD CURRENT 4.0
- *
- * s0ftpr0ject - digital security for y2k
- * www.s0ftpj.org
- *
- * sikurezza.org - italian security mailing list
- * www.sikurezza.org
- *
- */
-
- #include <sys/param.h>
- #include <sys/systm.h>
- #include <sys/kernel.h>
- #include <sys/malloc.h>
- #include <sys/mbuf.h>
- #include <sys/proc.h>
- #include <sys/protosw.h>
- #include <sys/socket.h>
- #include <sys/socketvar.h>
- #include <sys/sysctl.h>
-
- #include <vm/vm_zone.h>
-
- #include <net/if.h>
- #include <net/route.h>
-
- #define _IP_VHL
- #include <netinet/in.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netinet/in_pcb.h>
- #include <netinet/in_var.h>
- #include <netinet/ip_var.h>
- #include <netinet/ip_mroute.h>
-
-
- #define print_ip(a) printf("%d.%d.%d.%d\n", \
- (int)(ntohl(a) >>24) & 0xFF, \
- (int)(ntohl(a) >>16) & 0xFF, \
- (int)(ntohl(a) >> 8) & 0xFF, \
- (int)(ntohl(a)) & 0xFF);
-
-
- static int rip_new_send __P((struct socket *, int, struct mbuf *,
- struct sockaddr *, struct mbuf *,
- struct proc *));
-
- static int (*old_rip_send) __P((struct socket *, int, struct mbuf *,
- struct sockaddr *, struct mbuf *,
- struct proc *));
-
- static int rip_my_output __P((register struct mbuf *,
- struct socket *, u_long));
-
- static int s_load __P((struct module *, int, void *));
-
-
-
- /* il controllo si poteva fare direttamente su questa funzione.... non l'ho
- fatto perche' avevo gia' messo la mia rip_my_output nel sorgente :) */
-
-
- static int
- rip_new_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
- struct mbuf *control, struct proc *p)
- {
- struct inpcb *inp = sotoinpcb(so);
- register u_long dst;
-
- if (so->so_state & SS_ISCONNECTED) {
- if (nam) {
- m_freem(m);
- return EISCONN;
- }
- dst = inp->inp_faddr.s_addr;
- } else {
- if (nam == NULL) {
- m_freem(m);
- return ENOTCONN;
- }
- dst = ((struct sockaddr_in *)nam)->sin_addr.s_addr;
- }
- return rip_my_output(m, so, dst);
- }
-
- static int
- rip_my_output(m, so, dst)
- register struct mbuf *m;
- struct socket *so;
- u_long dst;
- {
- register struct ip *ip;
- register struct inpcb *inp = sotoinpcb(so);
- int flags = (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST;
-
-
-
- switch(inp->inp_ip_p) {
- case IPPROTO_RAW: printf("RAW");
- break;
- case IPPROTO_ICMP: printf("ICMP");
- break;
- case IPPROTO_IGMP: printf("IGMP");
- break;
- case IPPROTO_RSVP: printf("RSVP");
- break;
- case IPPROTO_IPIP: printf("IPIP");
- break;
- case IPPROTO_IDP: printf("IDP");
- break;
- default: printf("#%d", inp->inp_ip_p);
- break;
- }
-
- printf(" -> "); print_ip(dst);
-
- /*
- * If the user handed us a complete IP packet, use it.
- * Otherwise, allocate an mbuf for a header and fill it in.
- */
- if ((inp->inp_flags & INP_HDRINCL) == 0) {
- if (m->m_pkthdr.len + sizeof(struct ip) > IP_MAXPACKET) {
- m_freem(m);
- return(EMSGSIZE);
- }
- M_PREPEND(m, sizeof(struct ip), M_WAIT);
- ip = mtod(m, struct ip *);
- ip->ip_tos = 0;
- ip->ip_off = 0;
- ip->ip_p = inp->inp_ip_p;
- ip->ip_len = m->m_pkthdr.len;
- ip->ip_src = inp->inp_laddr;
- ip->ip_dst.s_addr = dst;
- ip->ip_ttl = MAXTTL;
- } else {
- if (m->m_pkthdr.len > IP_MAXPACKET) {
- m_freem(m);
- return(EMSGSIZE);
- }
- ip = mtod(m, struct ip *);
- /* don't allow both user specified and setsockopt options,
- and don't allow packet length sizes that will crash */
- if (((IP_VHL_HL(ip->ip_vhl) != (sizeof (*ip) >> 2))
- && inp->inp_options)
- || (ip->ip_len > m->m_pkthdr.len)
- || (ip->ip_len < (IP_VHL_HL(ip->ip_vhl) << 2))) {
- m_freem(m);
- return EINVAL;
- }
- if (ip->ip_id == 0)
- ip->ip_id = htons(ip_id++);
- /* XXX prevent ip_output from overwriting header fields */
- flags |= IP_RAWOUTPUT;
- ipstat.ips_rawout++;
- }
-
-
-
- return (ip_output(m, inp->inp_options, &inp->inp_route, flags,
- inp->inp_moptions));
- }
-
-
-
- extern struct protosw inetsw[];
-
- static int
- s_load (struct module *module, int cmd, void *arg)
- {
- int s;
-
- switch(cmd) {
- case MOD_LOAD:
- s=splnet();
- old_rip_send = inetsw[ip_protox[IPPROTO_ICMP]].pr_usrreqs->pru_send;
- inetsw[ip_protox[IPPROTO_ICMP]].pr_usrreqs->pru_send = rip_new_send;
- splx(s);
- break;
-
- case MOD_UNLOAD:
- s=splnet();
- inetsw[ip_protox[IPPROTO_ICMP]].pr_usrreqs->pru_send = old_rip_send;
- splx(s);
- break;
- }
-
- return 0;
- }
-
- static moduledata_t s_mod_1 = {
- "raww_mod",
- s_load,
- 0
- };
-
- DECLARE_MODULE(raww_mod, s_mod_1, SI_SUB_PSEUDO, SI_ORDER_ANY);
-